import std;
import grid;
import spreadsheet_cell;


// concepts demos
template <typename T>
concept Big = sizeof(T) >= 4;


// simple requirements
template <typename T>
concept Incrementable = requires(T x) {
	++x; x++;
};

// type requirements
// requires T to have a nested type named value_type
template <typename T>
concept C = requires { typename T::value_type; };

// compound requirements
template <typename T>
concept C2 = requires (T x, T y) {
	{ x.~T() } noexcept;
	{ x.swap(y) } noexcept;
};



auto main() -> int {
	Grid<int> myIntGrid{ 5, 5 };
	myIntGrid.at(0, 0) = 10;
	int x {myIntGrid.at(0, 0).value_or(0)};
	std::cout << "Value at (0, 0): " << x << std::endl;

	Grid<double> myDoubleGrid{ 2, 2 };
	myDoubleGrid.at(0, 0) = 3.14;
	double y {myDoubleGrid.at(0, 0).value_or(0.0)};
	std::cout << "Value at (0, 0): " << y << std::endl;

	Grid<int> myIntGrid2 {myIntGrid}; // copy constructor
	Grid<int> anotherIntGrid;
	anotherIntGrid = myIntGrid2; // copy assignment operator


	// grid of spreadsheet cell
	Grid<SpreadsheetCell> mySpreadsheet{ 3, 3 };
	SpreadsheetCell myCell{ 3.14 };
	mySpreadsheet.at(0, 0) = myCell;

	// concepts
	static_assert(Big<int>);
	static_assert(!Big<char>);
	static_assert(!Big<short>);
	static_assert(Big<long double>);

	return 0;
}